﻿#include "testrunner.h"
#include <QThread>

#include "common/datatypes.h"
#include <QThread>
#include <QtDebug>

TestRunner::TestRunner(QObject *parent)
    : QObject(parent)
{
}

/**
 * 设置测试计划：
 * - 重置会话池与活动会话
 * - 清零游标
 * - 清除停止标志
 * - 根据 plan->flowKind 创建流程策略实例（ITestFlow 的具体实现）
 */
void TestRunner::setPlan(Exec::TestPlanPtr testPlanPointer)
{
    // 先清理当前会话（RF静默 + 关闭 + reset）
    teardownActiveSession_();

    testPlan_ = testPlanPointer;
    activeSession_.reset();

    currentSubrangeIndex_ = 0;
    currentFrequencyIndex_ = 0;

    isStopRequestedAtomicFlag_.store(false, std::memory_order_relaxed);

    testFlow_ = createTestFlow(static_cast<HardwareTemplateType>(testPlan_->flowKind));
    if (!testFlow_) {
        emit errorOccurred("Create test flow failed.");
        emit stateChanged("Idle");
        return;
    }
    FlowPlanOptions opts;
    opts.stage = static_cast<TestProcessStage>(testPlan_->stage);
    opts.levelMode = static_cast<LevelModeType>(testPlan_->levelMode);
    opts.powerMeasurement = static_cast<PowerMeasurementType>(testPlan_->powerMeasurement);
    opts.immunityUnit = testPlan_->immunityUnit;
    opts.impedanceOhm = testPlan_->impedance_Ohm;
    opts.antennaFactor = static_cast<AntennaFactorType>(testPlan_->antennaFactor);
    testFlow_->setPlanOptions(opts);

    emit logMessage(QString("Plan set. Flow=%1").arg(testFlow_ ? testFlow_->name() : "null"));
    emit stateChanged("Idle");
}

/**
 * 设置当前游标位置：子区间索引 + 频点索引
 */
void TestRunner::setCursor(int subrangeIndex, int frequencyIndex)
{
    currentSubrangeIndex_ = subrangeIndex;
    currentFrequencyIndex_ = frequencyIndex;
}

/**
 * 停止请求：
 * - 设置原子标志
 * - 唤醒暂停等待
 * - 不会立即中断设备调用, 但在安全点检查后尽快退出
 */
void TestRunner::stop()
{
    isStopRequestedAtomicFlag_.store(true, std::memory_order_relaxed);

    QMutexLocker locker(&pauseMutex_);
    isPauseRequested_ = false;
    isPaused_ = false;
    pauseConditionVariable_.wakeAll();

    emit logMessage("Stop requested.");
}

/**
 * 暂停请求：
 * - 切换到暂停态（先安全静默, 后发 Paused 状态）
 * - 线程会在 waitIfPausedOrStopped 中阻塞等待
 */
void TestRunner::pause()
{
    QMutexLocker locker(&pauseMutex_);
    if (!isPaused_) {
        isPauseRequested_ = true;

        // 释放锁后做设备静默, 避免设备调用阻塞导致互斥锁长时间占用
        locker.unlock();
        safeMuteAllOutputs();
        locker.relock();

        isPaused_ = true;
        emit stateChanged("Paused");
        emit logMessage("Paused (RF muted).");
    }
}

/**
 * 恢复请求：
 * - 从暂停态恢复, 唤醒等待
 */
void TestRunner::resume()
{
    QMutexLocker locker(&pauseMutex_);
    if (isPaused_) {
        isPauseRequested_ = false;
        isPaused_ = false;
        pauseConditionVariable_.wakeAll();

        emit stateChanged("Running");
        emit logMessage("Resume requested.");
    }
}

//安全收尾清理
void TestRunner::shutdownAndRelease()
{
    //请求停止, 并唤醒暂停等待
    isStopRequestedAtomicFlag_.store(true, std::memory_order_relaxed);
    {
        QMutexLocker locker(&pauseMutex_);
        isPauseRequested_ = false;
        isPaused_ = false;
        pauseConditionVariable_.wakeAll();
    }

    //关闭并清空所有设备会话
    teardownActiveSession_();

    //释放流程与计划
    testFlow_.reset();
    testPlan_.reset();

    emit logMessage("Runner shutdown complete.");
    emit stateChanged("Idle");
}
/**
 * 单点测量：
 * - 校验当前游标合法性
 * - 确保当前子区间会话就绪
 * - 调 measurePointAt 进行一次测量
 */
void TestRunner::runSingle()
{
    if (!testPlan_ || !testFlow_) {
        emit errorOccurred("Plan/Flow not set");
        return;
    }
    if (currentSubrangeIndex_ < 0 || currentSubrangeIndex_ >= testPlan_->subranges.size()) {
        emit errorOccurred("Invalid subrange index");
        return;
    }

    const Exec::Subrange &currentSubrange = testPlan_->subranges[currentSubrangeIndex_];

    if (currentSubrange.freqPoints_Hz.isEmpty()
        || currentFrequencyIndex_ < 0
        || currentFrequencyIndex_ >= currentSubrange.freqPoints_Hz.size()) {
        emit errorOccurred("Invalid frequency index");
        return;
    }

    emit stateChanged("Running");
    isStopRequestedAtomicFlag_.store(false, std::memory_order_relaxed);

    if (!ensureSessionsForCurrentSubrange()) {
        emit errorOccurred("Ensure sessions failed");
        emit stateChanged("Idle");
        return;
    }

    while (!isStopRequestedAtomicFlag_.load(std::memory_order_relaxed)) {
        if (!measurePointAt(currentSubrangeIndex_, currentFrequencyIndex_)) {
            qCritical() << QString("Measure failed at subrange=%1, index=%2").arg(currentSubrangeIndex_).arg(currentFrequencyIndex_);
            emit errorOccurred("Measure failed");
            break;
        }
    }
    safeMuteAllOutputs();
    teardownActiveSession_();
    emit logMessage("Single Measure stopped.");
    emit stateChanged("Idle");
}

/**
 * 向前扫描：从当前频点向更大的方向（+1）移动
 */
void TestRunner::runSweepForward()
{
    sweep(true);
}

/**
 * 向后扫描：从当前频点向更小的方向（-1）移动
 */
void TestRunner::runSweepBackward()
{
    sweep(false);
}

void TestRunner::runLevelScanning(LevelScanningConfig config)
{
    teardownActiveSession_();
    isStopRequestedAtomicFlag_.store(false, std::memory_order_relaxed);
    levelScanningFlow_ = std::make_unique<LevelScanningFlow>();
    if (!levelScanningFlow_) {
        emit errorOccurred("Create test flow failed.");
        emit stateChanged("Idle");
        return;
    }
    TestFlowCallbacks callbacks;
    callbacks.isStopRequested = [this]() { return isStopRequestedAtomicFlag_.load(std::memory_order_relaxed); };
    callbacks.waitIfPaused = [this]() { this->waitIfPausedOrStopped(); };
    callbacks.logLine = [this](const QString &text) {
        // qDebug() <<   text;
        emit logMessage(text); };

    callbacks.levelScanData = [this](LevelScanningData &cct) {
        emit sig_levelScanData(cct);
    };
    callbacks.deviceMeasureStatus = [this](DeviceMeasureStatus &cct) {
        emit sig_updateDeviceStatus(cct);
    };

    QString errorMessage;
    emit stateChanged("Running");
    bool ok = levelScanningFlow_->measureLevelScanning(callbacks, config, errorMessage);
    if (!ok)
        emit errorOccurred(errorMessage);
    teardownActiveSession_();
    emit stateChanged("Idle");
    //    emit sweepFinished();
}
/**
 * 扫描骨架：
 * - 修正游标位置
 * - 确保会话
 * - 循环测量：测量当前点 -> 计算下一个点
 * - 若跨子区间：安全静默 + 发人工切换提示 + 等待 UI resume/stop + 确保新会话
 * - 结束后发 sweepFinished
 */
void TestRunner::sweep(bool isForwardDirection)
{
    if (!testPlan_ || !testFlow_) {
        emit errorOccurred("Plan/Flow not set");
        return;
    }
    if (testPlan_->subranges.isEmpty()) {
        emit errorOccurred("No subranges");
        return;
    }

    // 校正游标：子区间
    if (currentSubrangeIndex_ < 0)
        currentSubrangeIndex_ = 0;
    if (currentSubrangeIndex_ >= testPlan_->subranges.size())
        currentSubrangeIndex_ = testPlan_->subranges.size() - 1;

    // 校正游标：频点
    const Exec::Subrange &firstSubrange = testPlan_->subranges[currentSubrangeIndex_];
    if (firstSubrange.freqPoints_Hz.isEmpty()) {
        emit errorOccurred("subrange no points");
        return;
    }
    if (currentFrequencyIndex_ < 0)
        currentFrequencyIndex_ = 0;
    if (currentFrequencyIndex_ >= firstSubrange.freqPoints_Hz.size()) {
        currentFrequencyIndex_ = static_cast<int>(firstSubrange.freqPoints_Hz.size()) - 1;
    }

    emit stateChanged("Running");
    isStopRequestedAtomicFlag_.store(false, std::memory_order_relaxed);

    // 确保当前子区间会话
    if (!ensureSessionsForCurrentSubrange()) {
        emit errorOccurred("Ensure sessions failed");
        emit stateChanged("Idle");
        return;
    }

    int workingSubrangeIndex = currentSubrangeIndex_;
    int workingFrequencyIndex = currentFrequencyIndex_;

    // 工具函数：检查索引是否合法
    auto isIndexValid = [&](int checkSubrangeIndex, int checkFrequencyIndex) -> bool {
        if (checkSubrangeIndex < 0 || checkSubrangeIndex >= testPlan_->subranges.size())
            return false;

        const Exec::Subrange &subrange = testPlan_->subranges[checkSubrangeIndex];

        return (checkFrequencyIndex >= 0 && checkFrequencyIndex < subrange.freqPoints_Hz.size());
    };

    // 主循环
    while (!isStopRequestedAtomicFlag_.load(std::memory_order_relaxed)) {
        // 若处于暂停状态, 则阻塞等待 resume 或 stop
        waitIfPausedOrStopped();
        if (isStopRequestedAtomicFlag_.load(std::memory_order_relaxed))
            break;

        // 越界保护
        if (!isIndexValid(workingSubrangeIndex, workingFrequencyIndex))
            break;

        // 测量当前点
        if (!measurePointAt(workingSubrangeIndex, workingFrequencyIndex)) {
            qCritical() << QString("Measure failed at subrangeIndex=%1, freqIndex=%2").arg(workingSubrangeIndex).arg(workingFrequencyIndex);
            isStopRequestedAtomicFlag_.store(true, std::memory_order_relaxed);
            emit errorOccurred("Measure failed");
            break;
        }

        // 计算下一点
        int nextSubrangeIndex = workingSubrangeIndex;
        int nextFrequencyIndex = workingFrequencyIndex + (isForwardDirection ? 1 : -1);

        if (!isIndexValid(workingSubrangeIndex, nextFrequencyIndex)) {
            if (isStopRequestedAtomicFlag_.load(std::memory_order_relaxed))
                break;
            // 需要跨子区间
            nextSubrangeIndex = isForwardDirection ? (workingSubrangeIndex + 1) : (workingSubrangeIndex - 1);
            if (!isIndexValid(nextSubrangeIndex, 0))
                break; // 到头了
            nextFrequencyIndex = isForwardDirection
                                     ? 0
                                     : (static_cast<int>(testPlan_->subranges[nextSubrangeIndex].freqPoints_Hz.size()) - 1);

            // 跨子区间前：安全静默 + 提示人工切换 + 等待 UI 的 resume/stop
            safeMuteAllOutputs();
            emit manualChangeRequired(
                "需要人工切换",
                QString("即将从子区间 %1 切换到 %2, 请更换天线/硬件, 完成后点击继续")
                    .arg(workingSubrangeIndex + 1)
                    .arg(nextSubrangeIndex + 1));

            {
                QMutexLocker locker(&pauseMutex_);
                isPauseRequested_ = true;
                isPaused_ = true;
                emit stateChanged("Paused");
            }

            waitIfPausedOrStopped();
            if (isStopRequestedAtomicFlag_.load(std::memory_order_relaxed))
                break;

            // 切换到新子区间, 并确保新会话
            currentSubrangeIndex_ = nextSubrangeIndex;
            currentFrequencyIndex_ = nextFrequencyIndex;
            workingSubrangeIndex = nextSubrangeIndex;
            workingFrequencyIndex = nextFrequencyIndex;

            if (!ensureSessionsForCurrentSubrange()) {
                emit errorOccurred("Ensure sessions failed after changeover");
                break;
            }
            emit stateChanged("Running");
        } else {
            // 未跨子区间：仅更新索引
            workingSubrangeIndex = nextSubrangeIndex;
            workingFrequencyIndex = nextFrequencyIndex;

            currentSubrangeIndex_ = workingSubrangeIndex;
            currentFrequencyIndex_ = workingFrequencyIndex;
        }
    }
    safeMuteAllOutputs();
    teardownActiveSession_();
    emit stateChanged("Idle");
    emit sweepFinished();
}

/**
 * 若处于暂停状态, 则阻塞等待 resume 或 stop
 * - 当 stop 请求到来时, 也会唤醒并退出循环
 */
void TestRunner::waitIfPausedOrStopped()
{
    QMutexLocker locker(&pauseMutex_);
    while (isPauseRequested_ && !isStopRequestedAtomicFlag_.load(std::memory_order_relaxed)) {
        pauseConditionVariable_.wait(&pauseMutex_);
    }
}

/**
 * 确保“当前子区间”的会话对象就绪：
 * - 使用硬件键（subrange.hw.data()）做为缓存 key
 * - 若 activeSession_ 硬件一致, 直接使用
 * - 若会话池有缓存, 也直接复用
 * - 否则通过流程策略创建一个新会话, 并放入会话池
 */
bool TestRunner::ensureSessionsForCurrentSubrange()
{
    if (!testPlan_ || !testFlow_)
        return false;
    if (currentSubrangeIndex_ < 0 || currentSubrangeIndex_ >= testPlan_->subranges.size())
        return false;

    const Exec::Subrange &currentSubrange = testPlan_->subranges[currentSubrangeIndex_];
    const void *hardwareKey = currentSubrange.hw ? currentSubrange.hw.data() : nullptr;

    // 如果当前会话硬件一致, 直接复用（当前不使用复用功能）
    // if (activeSession_ && activeSession_->hardwareKey == hardwareKey)
    //     return true;

    // 硬件不同：先安全关闭旧会话, 再为新硬件创建
    teardownActiveSession_();

    // 通过流程策略创建新会话（可传入当前 activeSession_ 做复用候选）
    TestFlowSessionPtr newSession;
    TestFlowCallbacks callbacks;
    callbacks.deviceMeasureStatus = [this](DeviceMeasureStatus &cct) {
        emit sig_updateDeviceStatus(cct);
    };
    QString errorMessage;
    if (!testFlow_->ensureSessionsForSubrange(currentSubrange, activeSession_, newSession, callbacks, errorMessage)) {
        emit errorOccurred(QString("%1").arg(errorMessage));
        return false;
    }
    if (!newSession) {
        emit errorOccurred("returned null session");
        return false;
    }

    activeSession_ = std::move(newSession);

    emit logMessage("Sessions created by flow.");
    return true;
}

/**
 * 安全静默：关闭所有可能产生 RF 的设备
 * - 实际调用由流程策略负责（不同流程关闭不同设备）
 */
void TestRunner::safeMuteAllOutputs()
{
    if (testFlow_ && activeSession_) {
        testFlow_->safeMuteAllOutputs(activeSession_);
    }
    emit logMessage("RF outputs muted (safeMuteAllOutputs).");
}

/**
 * 测量指定子区间/频点：
 * - 校正当前游标
 * - 确保会话
 * - 组装回调（停止/暂停/日志）并调用流程策略的 measureOnePoint
 */
bool TestRunner::measurePointAt(int subrangeIndex, int frequencyIndex)
{
    currentSubrangeIndex_ = subrangeIndex;
    currentFrequencyIndex_ = frequencyIndex;

    // if (!ensureSessionsForCurrentSubrange())
    //     return false;

    const Exec::Subrange &subrange = testPlan_->subranges[subrangeIndex];

    // 向流程注入回调, 便于其内部逻辑随时检查停止/暂停和记录日志
    TestFlowCallbacks callbacks;
    callbacks.isStopRequested = [this]() { return isStopRequestedAtomicFlag_.load(std::memory_order_relaxed); };
    callbacks.waitIfPaused = [this]() { this->waitIfPausedOrStopped(); };
    callbacks.logLine = [this](const QString &text) {
        // qDebug() <<   text;
        emit logMessage(text); };

    callbacks.progress = [this](MeasurementPoint &cct) {
        cct.subrangeIndex = currentSubrangeIndex_;
        cct.frequencyIndex = currentFrequencyIndex_;
        emit pointProgress(cct);
    };
    callbacks.deviceMeasureStatus = [this](DeviceMeasureStatus &cct) {
        emit sig_updateDeviceStatus(cct);
    };

    QString errorMessage;
    bool ok = testFlow_->measureOnePoint(subrange, frequencyIndex, activeSession_, callbacks, errorMessage);
    if (!ok) {
        // safeMuteAllOutputs();
        // teardownActiveSession_();
        emit errorOccurred(errorMessage);
    }
    return ok;
}

void TestRunner::teardownActiveSession_()
{
    // 注意：此函数在 Runner 线程中调用
    if (activeSession_) {
        try {
            activeSession_->safeMuteAllOutputs();
        } catch (...) {
        }
        try {
            activeSession_->closeAll();
        } catch (...) {
        }
        activeSession_.reset();
        emit logMessage("Active session closed.");
    }
    DeviceMeasureStatus dms;
    dms.stat = DeviceStatus::DisConnect;
    dms.role = DeviceRole::SignalGenerator;
    emit sig_updateDeviceStatus(dms);
    dms.role = DeviceRole::Amplifier;
    emit sig_updateDeviceStatus(dms);
    dms.role = DeviceRole::PowerMeterForward;
    emit sig_updateDeviceStatus(dms);
    dms.role = DeviceRole::PowerMeterReverse;
    emit sig_updateDeviceStatus(dms);
    dms.role = DeviceRole::PowerMeterMonitor;
    emit sig_updateDeviceStatus(dms);
    dms.role = DeviceRole::Receiver;
    emit sig_updateDeviceStatus(dms);
}
